home *** CD-ROM | disk | FTP | other *** search
Text File | 1997-12-08 | 13.5 KB | 561 lines | [TEXT/ALFA] |
- ## -*-Tcl-*-
- # ###################################################################
- #
- # FILE: "shellMode.tcl"
- # last update: 8/12/97 {10:30:24 am}
- # Author: Vince Darley, Pete Keleher
- # E-mail: <darley@fas.harvard.edu>
- # mail: Division of Engineering and Applied Sciences, Harvard University
- # Oxford Street, Cambridge MA 02138, USA
- # www: <http://www.fas.harvard.edu/~darley/>
- #
- # Some Copyright (c) 1997 Vince Darley
- # Some copyright Pete Keleher.
- #
- # Description:
- #
- # General purpose shell routines for Alpha. Two and a half shells
- # are provided by default: the Alpha Tcl shell, the MPW toolserver
- # shell and half of the comet shell (whatever that is).
- #
- # A separate package 'remotetclshell' allows Alpha to act as a console
- # for a separately running Wish.
- # ###################################################################
- ##
-
- alpha::mode Shel 1.7.2 dummyShel {"*tcl\ sh*"} tclMenu {
- regModeKeywords -m {«} Shel {}
- addMode MPW {} {"*Toolserver\ *"} {}
- # we use our own version since Alpha doesn't quite change mode
- # to Shel correctly (not sure what it does wrong).
- catch {rename shell {}}
- # we do this ourselves. this way we don't need a special hack
- # in 'openHook'
- catch {rename toolserverShell {}}
- }
-
- newPref v wordBreak {(\$)?[a-zA-Z0-9_.]+} Shel
- newPref f wordWrap {0} Shel
- newPref v wordBreakPreface {[^a-zA-Z0-9_\$]} Shel
- newPref f autoMark 0 Shel
- newPref f tcl_interactive 1 Shel
- set invisibleModeVars(tcl_interactive) 1
- set Shel::endPara {^«.*$}
- set Shel::startPara {^«.*$}
- ensureset Shel::histnum 0
-
- bind '\r' Shel::carriageReturn "Shel"
- bind '\r' Shel::carriageReturn "MPW"
- bind '\t' bind::Completion Shel
-
- bind up <z> Shel::prevHist Shel
- bind down <z> Shel::nextHist Shel
-
- bind 'a' <z> Shel::Bol Shel
- bind up Shel::up Shel
- bind down Shel::down Shel
-
- bind 'u' <z> Shel::killLine Shel
-
- proc dummyShel {} {}
-
- ensureset otherDirs {}
-
- proc Shel::OptionTitlebar {} {
- regsub -all "\n *" [history] "\} \{" h
- set h "\{[string trim $h]\}"
- }
-
- proc Shel::OptionTitlebarSelect {item} {
- insertText [string range $item [expr 2+[string first " " $item]] end]
- Shel::carriageReturn
- }
-
- proc Shel::DblClick {args} { eval Tcl::DblClick $args }
-
- ##
- # -------------------------------------------------------------------------
- #
- # "Shel::carriageReturn" --
- #
- # Rewritten to avoid need for global _text _return variables
- # -------------------------------------------------------------------------
- ##
- proc Shel::carriageReturn {} {
- global mode histnum Shel::Type
- set pos [getPos]
-
- if {![catch {regexp {∞} [getText $pos [nextLineStart $pos]]} res] && $res} {
- gotoMatch; return;
- }
- set ind [string first "»" [getText [lineStart $pos] $pos]]
- if {$ind < 0} {
- insertText "\r"
- return
- }
- endOfLine
- set fileName [win::CurrentTail]
- set type [set Shel::Type($fileName)]
- # sort out where we're going to put the answer
- set t [getText [expr [lineStart $pos]+$ind+2] [getPos]]
- if {[getPos] != [maxPos]} {
- goto [set pos [maxPos]]
- set ind [string first "»" [getText [lineStart $pos] $pos]]
- if {$ind < 0} {
- insertText "\r" [${type}::Prompt]
- } else {
- incr ind [expr 2 + [lineStart $pos]]
- if {$ind != $pos} {
- deleteText $ind $pos
- }
- }
- insertText -w $fileName $t
- }
- # carry out the action
- set r [${type}::eval $t]
- insertText -w $fileName "\r" $r
- if {$r != ""} {
- insertText -w $fileName "\r"
- }
- insertText -w $fileName [${type}::Prompt]
- }
-
- proc Shel::start {type {title ""} {startuptext ""}} {
- if {$title != ""} {
- if ![catch {bringToFront $title}] {
- return
- }
- new -n $title -m Shel
- setWinInfo shell 1
- if {$startuptext != ""} {
- insertText $startuptext
- }
- }
- global Shel::Type
- set c [win::Current]
- set Shel::Type($c) $type
- insertText -w $c [${type}::Prompt]
- }
-
- # ◊◊◊◊ Alpha shell routines ◊◊◊◊ #
-
- proc tclLog {string} {
- catch {insertText -w "*tcl shell*" "\r" $string}
- }
-
- proc shell {} {
- Shel::start "Alpha" "*tcl shell*" "Welcome to Alpha's Tcl shell.\r"
- }
-
- namespace eval Alpha {}
-
- proc Alpha::eval {t} {
- global errorInfo Shel::histnum
- history add $t
- if {[set code [catch {uplevel \#0 $t} msg]] == 1} {
- # strip off end of error due to 'uplevel' command
- set new [split $errorInfo \n]
- set new [join [lrange $new 0 [expr [llength $new] - 4]] \n]
- set errorInfo "$new"
- set msg "Error: $msg"
- }
- set Shel::histnum [history nextid]
- return $msg
- }
- proc Alpha::Prompt {} {
- return "«[file tail [string trimright [pwd] {:}]]» "
- }
-
- # ◊◊◊◊ MPW routines ◊◊◊◊ #
- namespace eval mpw {}
- proc mpw::eval {t} {
- catch {dosc -n ToolServer -s $t} r
- return $r
- }
- proc mpw::Prompt {} { return "«mpw» " }
- proc toolserverShell {} {
- Shel::start "mpw" {*Toolserver shell*} \
- "Welcome to Alpha's MPW shell (using ToolServer via AppleEvents).\r"
- if [catch {app::ensureRunning ToolServer MPSX}] {
- killWindow
- }
- }
-
- # ◊◊◊◊ Comet routines ◊◊◊◊ #
- namespace eval comet {}
- proc comet::eval {t} {
- cometSendAndPrompt $t
- return ""
- }
- proc comet::Prompt {} {}
-
- # ◊◊◊◊ General purpose ◊◊◊◊ #
-
- proc Shel::prevHist {} {
- global Shel::histnum Shel::curCmdLine
-
- set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
- if {[set ind [string first "» " $text]] > 0} {
- goto [expr [lineStart [getPos]] + $ind + 2]
- } else return
-
- incr Shel::histnum -1
- if {[catch {history event ${Shel::histnum}} text]} {
- incr Shel::histnum
- endOfLine
- beep
- return
- }
- set to [nextLineStart [getPos]]
- if {[lookAt [expr $to-1]] == "\r"} {incr to -1}
- if { [expr ${Shel::histnum} + 1] == [history nextid] } {
- set Shel::curCmdLine [getText [getPos] $to]
- }
- replaceText [getPos] $to $text
- }
-
-
- proc Shel::nextHist {} {
- global Shel::histnum Shel::curCmdLine
-
- set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
- if {[set ind [string first "» " $text]] > 0} {
- goto [expr [lineStart [getPos]] + $ind + 2]
- } else return
-
- if {${Shel::histnum} == [history nextid]} {
- beep
- endOfLine
- return
- }
-
- incr Shel::histnum
- if {${Shel::histnum} == [history nextid]} {
- set text ${Shel::curCmdLine}
- } else {
- if {[catch {history event ${Shel::histnum}} text]} {
- endOfLine
- return
- }
- }
- set to [nextLineStart [getPos]]
- if {[lookAt [expr $to-1]] == "\r"} {incr to -1}
- replaceText [getPos] $to $text
- }
-
- proc Shel::killLine {} {
- set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
- if {[set ind [string first "» " $text]] > 0} {
- goto [expr [lineStart [getPos]] + $ind + 2]
- } else {
- return
- }
- set to [nextLineStart [getPos]]
- if {[lookAt [expr $to-1]] == "\r"} {incr to -1}
- deleteText [getPos] $to
- }
-
- proc Shel::Bol {} {
- set text [getText [lineStart [getPos]] [nextLineStart [getPos]]]
- if {[set ind [string first "» " $text]] > 0} {
- goto [expr [lineStart [getPos]] + $ind + 2]
- } else {
- goto [lineStart [getPos]]
- }
- }
-
- proc Shel::up {} {
- set pos [expr [lineStart [getPos]] - 1]
- if {[catch {regexp {∞} [getText [lineStart $pos] [nextLineStart $pos]]} res] || !$res} {
- previousLine; return
- }
- select [lineStart $pos] [nextLineStart $pos]
- }
-
- proc Shel::down {} {
- set pos [nextLineStart [getPos]]
- if {[catch {regexp {∞} [getText $pos [nextLineStart $pos]]} res] || !$res} {
- nextLine; return
- }
- select $pos [nextLineStart $pos]
- }
-
- # ◊◊◊◊ Unix imitation ◊◊◊◊ #
-
- proc l {args} {
- eval [concat "ls -CF" $args]}
-
- proc ll {args} {
- eval [concat "ls -l" $args]}
-
-
- proc wc {args} {
- set res {}
- set totChars 0
- set totLines 0
- set totWords 0
- set args [glob -nocomplain $args]
- foreach file $args {
- set id [open $file]
- set chars [string length [set text [read $id]]]
- set lines [llength [split $text "\n"]]
- set words [llength [split $text]]
- append res [format "\r%8d%8d%8d $file" $lines $words $chars]
- set totChars [expr $totChars+$chars]
- set totWords [expr $totWords+$words]
- set totLines [expr $totLines+$lines]
- close $id
- }
- if {[llength $args] > 1} {
- append res [format "\r%8d%8d%8d total" $totLines $totWords $totChars]
- }
- return [string range $res 1 end]
- }
-
-
-
- #================================================================================
- # To prevent ambiguity, 'from' is assumed to be a complete pathname, ending
- # in a directory name. If it doesn't end w/ a colon, one is added. 'to' is
- # assumed to be the parent directory of the top directory we are creating.
- #================================================================================
- proc cpdir {from to} {
- set cwd [pwd]
- if {[string match ":*" $from] || [string match ":*" $to] ||
- ![file exists $from] || ![file exists $to]} {
- error "'cpdir' args must be complete pathnames of existing folders."
- }
- if {![string match "*:" $from]} {append from ":"}
- if {![string match "*:" $to]} {append to ":"}
-
- if {![file isdir $from] || ![file isdir $to]} {
- exit 1
- }
-
- set res [catch {cphier $from $to} val]
- cd $cwd
- if {$res} {error $val}
- }
-
- proc cphier {from to} {
- set savedir [pwd]
- if {[string index $from [expr [string len $from] - 1]] != ":"} {append from ":"}
- set dir [file tail [string trimright $from ":"]]
- cd $to
- mkdir "$dir"
- foreach f [glob "$from*"] {
- if {[file isdir $f]} {
- cphier "$f:" "$to$dir:"
- } else {
- cp $f $to$dir:
- }
- }
- cd $savedir
- }
-
-
- #================================================================================
- #####
- # (Usage: 'lt' sorts by time, like UNIX's 'ls -lt'.
- # 'lt -t' sorts by filename, like UNIX's 'ls -l'.
- # Optionally a directory name can be added as an argument.)
-
- proc sortdt {dt} {
- scan $dt "%d/%d/%d {%d:%d:%d %1sM}" mon day yea hou min sec z
- if {$z == "P"} {incr hou 12}
- if {[string length $yea] == 1} {
- set year 200$yea
- } elseif {$yea > 40} {
- set year 19$yea
- } else {
- set year 20$yea
- }
- return [format "%04d%02d%02d%02d%02d" $year $mon $day $hou $min]
- }
-
-
- proc lth args {
- global mode
-
- set val "*"
- set sort 1
- scan [lindex [mtime [now]] 0] "%d/%d/%d" one two three
- if {[string length $three] == 1} {
- set year 200$three
- } elseif {$three > 40} {
- set year 19$three
- } else {
- set year 20$three
- }
-
- foreach arg $args {
- switch -- $arg {
- "-t" {set sort 0}
- default {set val $arg}
- }
- }
- set mod ""
- foreach f [eval glob $val] {
- if {[catch {getFileInfo $f info}]} {
- if {$sort} {set mod "000000000000 "}
- lappend text [format "%s%s %8d%8d %6s %5s %4s %s %s\n" $mod "D" "0" "0" "" "" "" "DIR " [file tail $f]]
- continue
- }
- if {$sort} {set mod "[sortdt [mtime $info(modified) s]] "}
- set m [mtime $info(modified) a]
- set zer [lindex $m 0]
- set dat [format "%s %2s" [lindex $zer 1] [string trimright [lindex $zer 2] {,}]]
- if {[lindex $zer 3] == $year} {
- if {[scan [lindex $m 1] "%d:%d:%d %s" one two three am] != 4} {
- error "Didn't get four from scan"
- }
- if {[string length $two] == 1} {set two "0$two"}
- set tm [expr {$am == "AM"} ? $one : [expr $one + 12]]:$two
- } else {
- set tm " [lindex $zer 3]"
- }
- lappend text [format "%sF %8d%8d %s %5s %s %s %s\n" $mod $info(datalen) $info(resourcelen) $dat $tm $info(type) $info(creator) [file tail $f]]
- }
- if {$sort} {
- foreach ln [lsort -de $text] {
- append txt [string range $ln 13 end]
- }
- set ans [string trimright $txt]
- } else {
- set ans [string trimright [join $text {}]]
- }
-
- if { $mode=="Shel" } { return $ans } else {
- new
- insertText $ans "\r"
- catch shrinkHeight
- setWinInfo dirty 0
- setWinInfo read-only 1
- }
- }
-
- #================================================================================
- proc ps {} {
- foreach p [processes] {
- append text [format "%-25s %4s %10d %10d\r" [lindex $p 0] [lindex $p 1] [lindex $p 2] [lindex $p 3]]
- }
- return [string trimright $text]
- }
-
-
- #================================================================================
- # Recursively make creator of all text files 'ALFA'. Optionally takes a starting
- # dir argument, otherwise starts in current directory. Auto-Doubled are no
- # longer recognized by auto-doubler! Why? Some sort of conflict w/ 'PBSetFInfo'.
- proc creator {{dir ":"}} {
- if {![catch {glob -t TEXT $dir*} files]} {
- foreach f $files {
- message $f
- setFileInfo $f creator ALFA
- }
- }
-
- if {![catch {glob $dir*} dirs]} {
- foreach d $dirs {
- if {[file isdir $d]} {creator $d:}
- }
- }
- }
-
-
- #===============================================================================
-
- proc tomac args {
- set files {}
- foreach arg $args {
- append files " " [glob $arg]
- }
- set dir [pwd]
-
- foreach f $files {
- message "$f..."
- set fd [open $dir$f "r"]
- set text [read $fd]
- close $fd
- regsub -all "\n" $text "\r" text
-
- set fd [open "$dir$f" "w"]
- puts -nonewline $fd $text
- close $fd
- }
- message ""
- }
-
-
- #===============================================================================
-
- proc unixToMac {fname} {
- set fd [open $fname]
- set text [read $fd]
- close $fd
- set fd [open $fname "w"]
- puts -nonewline $fd $text
- close $fd
- }
-
- proc setCreator args {
- set files {}
- set creator [car $args]
- foreach arg [cdr $args] {
- append files " " [glob $arg]
- }
-
- foreach f $files {
- setFileInfo $f creator $creator
- }
- }
-
- proc setType args {
- set files {}
- set type [car $args]
- foreach arg [cdr $args] {
- append files " " [glob $arg]
- }
-
- foreach f $files {
- setFileInfo $f type $type
- }
- }
- #===============================================================================
-
- proc pushd {args} {
- global otherDirs
- if {[string length $args]} {
- set otherDirs [cons [pwd] $otherDirs]
- cd [string trim [eval list $args] " \{\}"]
- } else {
- if {[llength $otherDirs]} {
- set n [car $otherDirs]
- set otherDirs [cons [pwd] [cdr $otherDirs]]
- cd $n
- } else {
- return "No other directories"
- }
- }
- }
- proc pd {args} {
- if {[string length $args]} {
- eval pushd $args
- } else {
- pushd
- }
- }
-
-
- proc dirs {} {global otherDirs; cons [pwd] $otherDirs}
-
- proc popd {} {
- global otherDirs
- if {[llength $otherDirs]} {
- cd [car $otherDirs]
- set otherDirs [cdr $otherDirs]
- } else {
- return "No other directories"
- }
- }
-